home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
frasrc19.zip
/
FRACSUBA.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-02-15
|
24KB
|
1,038 lines
; FRACASM.ASM - Assembler subroutines for fractals.c
; required for compatibility if Turbo ASM
IFDEF ??version
MASM51
QUIRKS
ENDIF
.MODEL medium,c
.8086
; these must NOT be in any segment!!
; this get's rid of TURBO-C fixup errors
extrn multiply:far ; this routine is in 'general.asm'
extrn floatbailout:word ; this routine is in 'fractals.c'
.data
extrn lold:qword, lnew:qword ; each defined as LCMPLX in fractals.c
extrn ltempsqrx:dword ; for fractals.c
extrn ltempsqry:dword ; for fractals.c
extrn lmagnitud:dword ; for fractals.c
extrn llimit:dword ; from calcfrac.c
extrn llimit2:dword ; from calcfrac.c
extrn bitshift:word ; fudgefactor for integer math
extrn overflow:word ; error from integer math
.code FRACTALS_TEXT
;; Note: the check for overflow is now in StandardFractal(), JCO 2/12/95
asmlMODbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; lmagnitud = ltempsqrx + ltempsqry;
; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
; || labs(lnew.y) > llimit2 || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
; if (lmagnitud >= llimit
cmp dx,WORD PTR llimit+2
jl chkvs0
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || lmagnitud < 0
chkvs0: or dx,dx
js bailout
; || labs(lnew.x) > llimit2 ; This test and next one are extraneous:
; mov ax,WORD PTR lnew ; take x > llimit2 and sqr both sides
; mov dx,WORD PTR lnew+2 ; x^2 > llimit
; or dx,dx ; if x^2 > llimit then surely
; jge lnewx ; x^2 + y^2 > llimit
; neg ax ; which was just checked!
; adc dx,0
; neg dx
;lnewx: cmp dx,WORD PTR llimit2+2
; jl chklnewy
; jg bailout
; cmp ax,WORD PTR llimit2
; ja bailout
; || labs(lnew.y) > llimit2
;chklnewy:
; mov ax,WORD PTR lnew+4
; mov dx,WORD PTR lnew+6
; or dx,dx
; jge lnewy
; neg ax
; adc dx,0
; neg dx
;lnewy: cmp dx,WORD PTR llimit2+2
; jl chkoflow
; jg bailout
; cmp ax,WORD PTR llimit2
; ja bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlMODbailout endp
asmlREALbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqry
adc dx,WORD PTR ltempsqry+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqrx ; restore ltempsqrx to ax & dx
mov dx,WORD PTR ltempsqrx+2
; if (ltempsqrx >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlREALbailout endp
asmlIMAGbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if (ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlIMAGbailout endp
asmlORbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if (ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkxnxt
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || ltempsqrx >= llimit
chkxnxt:
mov ax,WORD PTR ltempsqrx
mov dx,WORD PTR ltempsqrx+2
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlORbailout endp
asmlANDbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push WORD PTR lnew+2
push WORD PTR lnew
push WORD PTR lnew+2
push WORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push WORD PTR lnew+6
push WORD PTR lnew+4
push WORD PTR lnew+6
push WORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
add ax,WORD PTR ltempsqrx
adc dx,WORD PTR ltempsqrx+2
mov WORD PTR lmagnitud,ax
mov WORD PTR lmagnitud+2,dx
mov ax,WORD PTR ltempsqry ; restore ltempsqry to ax & dx
mov dx,WORD PTR ltempsqry+2
; if ((ltempsqry >= llimit
cmp dx,WORD PTR llimit+2
jl chkoflow
jg chkx
cmp ax,WORD PTR llimit
jae chkx
jmp short chkoflow
; && ltempsqrx >= llimit)
chkx: mov ax,WORD PTR ltempsqrx
mov dx,WORD PTR ltempsqrx+2
cmp dx,WORD PTR llimit+2
jl chkoflow
jg bailout
cmp ax,WORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov ax,WORD PTR lnew
mov dx,WORD PTR lnew+2
mov WORD PTR lold,ax
mov WORD PTR lold+2,dx
mov ax,WORD PTR lnew+4
mov dx,WORD PTR lnew+6
mov WORD PTR lold+4,ax
mov WORD PTR lold+6,dx
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asmlANDbailout endp
.386
asm386lMODbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; lmagnitud = ltempsqrx + ltempsqry;
; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
; || labs(lnew.y) > llimit2 || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push DWORD PTR lnew
push DWORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push DWORD PTR lnew+4
push DWORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
mov eax,DWORD PTR ltempsqry
add eax,DWORD PTR ltempsqrx
mov DWORD PTR lmagnitud,eax
; if (lmagnitud >= llimit
cmp eax,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lMODbailout endp
asm386lREALbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqry = lsqr(lnew.y);
push bitshift
push DWORD PTR lnew+4
push DWORD PTR lnew+4
call FAR PTR multiply
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; ltempsqrx = lsqr(lnew.x);
push bitshift
push DWORD PTR lnew
push DWORD PTR lnew
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
mov eax,DWORD PTR ltempsqry
add eax,DWORD PTR ltempsqrx
mov DWORD PTR lmagnitud,eax
; if (ltempsqrx >= llimit
mov eax,DWORD PTR ltempsqrx
cmp eax,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lREALbailout endp
asm386lIMAGbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push DWORD PTR lnew
push DWORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push DWORD PTR lnew+4
push DWORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
mov eax,DWORD PTR ltempsqry
add eax,DWORD PTR ltempsqrx
mov DWORD PTR lmagnitud,eax
; if (ltempsqry >= llimit
mov eax,DWORD PTR ltempsqry
cmp eax,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lIMAGbailout endp
asm386lORbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push DWORD PTR lnew
push DWORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push DWORD PTR lnew+4
push DWORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
mov eax,DWORD PTR ltempsqry
add eax,DWORD PTR ltempsqrx
mov DWORD PTR lmagnitud,eax
; if (ltempsqry >= llimit
mov eax,DWORD PTR ltempsqry
cmp eax,DWORD PTR llimit
jae bailout
; || ltempsqrx >= llimit
chkxnxt:
mov eax,DWORD PTR ltempsqrx
cmp eax,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lORbailout endp
asm386lANDbailout proc near
;
; equivalent to the C code:
; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
; if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
; { overflow=0; return(1); }
; lold = lnew;
; return(0);
;
; ltempsqrx = lsqr(lnew.x);
push bitshift
push DWORD PTR lnew
push DWORD PTR lnew
call FAR PTR multiply
mov WORD PTR ltempsqrx,ax
mov WORD PTR ltempsqrx+2,dx
; ltempsqry = lsqr(lnew.y);
push bitshift
push DWORD PTR lnew+4
push DWORD PTR lnew+4
call FAR PTR multiply
add sp,20
mov WORD PTR ltempsqry,ax
mov WORD PTR ltempsqry+2,dx
; lmagnitud = ltempsqrx + ltempsqry;
mov eax,DWORD PTR ltempsqry
add eax,DWORD PTR ltempsqrx
mov DWORD PTR lmagnitud,eax
; if ((ltempsqry >= llimit
mov eax,DWORD PTR ltempsqry
cmp eax,DWORD PTR llimit
jl chkoflow
; && ltempsqrx >= llimit)
chkx: mov eax,DWORD PTR ltempsqrx
cmp eax,DWORD PTR llimit
jae bailout
; || overflow)
chkoflow:
; cmp overflow,0
; jne bailout
; else {
; lold = lnew;
mov eax,DWORD PTR lnew
mov DWORD PTR lold,eax
mov eax,DWORD PTR lnew+4
mov DWORD PTR lold+4,eax
; return(0); }
sub ax,ax
ret
bailout:
; { overflow=0; return(1); }
; mov overflow,0
mov ax,1
ret
asm386lANDbailout endp
; Fast fractal orbit calculation procs for Fractint.
; By Chuck Ebbert CIS: (76306,1226)
;
; FManOWarfpFractal()
; FJuliafpFractal()
; FBarnsley1FPFractal()
; FBarnsley2FPFractal()
; FLambdaFPFractal()
;
; asmfloatbailout() -- bailout proc (NEAR proc used by above)
; NOTE: asmfloatbailout() modifies SI and DI.
;
; These will only run on machines with a 287 or a 387 (and a 486 of course.)
;
; Some of the speed gains from this code are due to the storing of the NPU
; status word directly to the AX register. FRACTINT will use these
; routines only when it finds a 287 or better coprocessor installed.
.286
.287
.data
extrn new:qword, old:qword, tmp:qword
extrn rqlim:qword, magnitude:qword, tempsqrx:qword, tempsqry:qword
extrn cpu:word, fpu:word, floatparm:word
.code FRACTALS_TEXT
; px,py = floatparm->x,y
; ox,oy = oldx,oldy
; nx,ny = newx,newy
; nx2,ny2 = newxsquared,newysquared
; tx,ty = tempx, tempy (used in lambda)
FManOWarfpFractal proc uses si di
; From Art Matrix via Lee Skinner
fld tempsqrx ; ox2
fsub tempsqry ; ox2-oy2
mov bx,floatparm
fadd tmp ; ox2-oy2+tx
fadd qword ptr [bx] ; newx
fld old ; oldx newx
fmul old+8 ; oldx*oldy newx
fadd st,st ; oldx*oldy*2 newx
fadd tmp+8 ; oldx*oldy*2+tmp.y newx
fadd qword ptr [bx+8] ; newy newx
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
mov si,offset old ; tmp=old
mov di,offset tmp
mov ax,ds
mov es,ax
mov cx,8
rep movsw
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FManOWarfpFractal endp
FJuliafpFractal proc uses si di
; Julia/Mandelbrot floating-point orbit function.
fld tempsqrx
fsub tempsqry
mov bx,floatparm
fadd qword ptr [bx] ;/* add floatparm->x */
fld qword ptr old ;/* now get 2*x*y+floatparm->y */
fmul qword ptr old+8
fadd st,st
fadd qword ptr [bx+8] ; add floatparm->y
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FJuliafpFractal endp
FBarnsley1FPFractal proc uses si di
; From Fractals Everywhere by Michael Barnsley
mov bx,floatparm
fld qword ptr [bx] ;/* STACK: px */
fld qword ptr [bx+8] ;/* py px */
fld qword ptr old ;/* ox py px */
ftst ;/*** we will want this later */
fstsw ax ;/*** 287 or better only */
fld old+8 ;/* oy ox py px */
fld st(1) ;/* ox oy ox py px */
fmul st,st(4) ;/* ox*px oy ox py px */
fld st(1) ;/* oy ox*px oy ox py px */
fmul st,st(4) ;/* oy*py ox*px oy ox py px */
fsub ;/* (ox*px-oy*py) oy ox py px */
fxch ;/* oy (oxpx-oypy) ox py px */
fmul st,st(4) ;/* oy*px (oxpx-oypy) ox py px */
fxch st(2) ;/* ox (oxpx-oypy) oy*px py px */
fmul st,st(3) ;/* ox*py (oxpx-oypy) oy*px py px */
faddp st(2),st ;/* oxpx-oypy oypx+oxpy py px */
sahf ;/*** use the saved status (finally) */
jb BFPM1add
fsubrp st(3),st ;/* oypx+oxpy py nx */
fsubr ;/* ny nx */
jmp short BFPM1cont
BFPM1add:
faddp st(3),st ;/* oypx+oxpy py nx */
fadd ;/* ny nx */
BFPM1cont:
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FBarnsley1FPFractal endp
FBarnsley2FPFractal proc uses si di
; Also from Fractals Everywhere
mov bx,floatparm
fld qword ptr [bx] ;/* STACK: px */
fld qword ptr [bx+8] ;/* py px */
fld qword ptr old ;/* ox py px */
fld qword ptr old+8 ;/* oy ox py px */
fld st(1) ;/* ox oy ox py px */
fmul st,st(4) ;/* ox*px oy ox py px */
fld st(1) ;/* oy ox*px oy ox py px */
fmul st,st(4) ;/* oy*py ox*px oy ox py px */
fsub ;/* (ox*px-oy*py) oy ox py px */
fxch st(2) ;/* ox oy (oxpx-oypy) py px */
fmul st,st(3) ;/* ox*py oy (oxpx-oypy) py px */
fxch ;/* oy ox*py (oxpx-oypy) py px */
fmul st,st(4) ;/* oy*px ox*py (oxpx-oypy) py px */
fadd ;/* oypx+oxpy oxpx-oypy py px */
ftst
fstsw ax ;/* 287 or better only */
sahf
jb BFPM2add
fsubrp st(2),st ;/* oxpx-oypy ny px */
fsubrp st(2),st ;/* ny nx */
jmp short BFPM2cont
BFPM2add:
faddp st(2),st ;/* oxpx-oypy ny px */
faddp st(2),st ;/* ny nx */
BFPM2cont:
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FBarnsley2FPFractal endp
FLambdaFPFractal proc uses si di
; tempsqrx and tempsqry can be used -- the C code doesn't use them!
fld tempsqry ;oy2
fsub tempsqrx ;oy2-ox2
fld old ;ox oy2-ox2
fadd st(1),st ;ox tx=ox+oy2-ox2
fadd st,st ;2ox tx
fld1 ;1 2ox tx
fsubr ;(1-2ox) tx
fmul old+8 ;ty=oy(1-2ox) tx
fld st(1) ;tx ty tx -- duplicate these now
fld st(1) ;ty tx ty tx
mov bx,floatparm
fld qword ptr [bx+8] ;py ty tx ty tx -- load y first
fld qword ptr [bx] ;px py ty tx ty tx
fmul st(5),st ;px py ty tx ty pxtx
fmulp st(4),st ;py ty tx pxty pxtx
fmul st(2),st ;py ty pytx pxty pxtx
fmul ;pyty pytx pxty pxtx
fsubp st(3),st ;pytx pxty nx=pxtx-pyty
fadd ;ny=pxty+pytx nx
fstp qword ptr new+8 ; newx
fstp qword ptr new ; stack is empty
; call near ptr asmfloatbailout
call word ptr [floatbailout]
ret
FLambdaFPFractal endp
; The following is no longer used.
asmfloatbailout proc near
; called with new.y and new.x on stack and clears the stack
; destroys SI and DI: caller must save them
fst qword ptr new+8
fmul st,st ;/* ny2 nx */
fst tempsqry
fxch ;/* nx ny2 */
fst qword ptr new
fmul st,st ;/* nx2 ny2 */
fst tempsqrx
fadd
fst magnitude
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfloatbailout endp
; The preceeding is no longer used.
asmfpMODbailout proc near uses si di
fld qword ptr new+8
fmul st,st ;/* ny2 */
fst tempsqry
fld qword ptr new ;/* nx ny2 */
fmul st,st ;/* nx2 ny2 */
fst tempsqrx
fadd
fst magnitude
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfpMODbailout endp
asmfpREALbailout proc near uses si di
fld qword ptr new
fmul st,st ;/* nx2 */
fst tempsqrx
fld qword ptr new+8 ;/* ny nx2 */
fmul st,st ;/* ny2 nx2 */
fst tempsqry ;/* ny2 nx2 */
fadd st,st(1) ;/* ny2+nx2 nx2 */
fstp magnitude ;/* nx2 */
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfpREALbailout endp
asmfpIMAGbailout proc near uses si di
fld qword ptr new+8
fmul st,st ;/* ny2 */
fst tempsqry
fld qword ptr new ;/* nx ny2 */
fmul st,st ;/* nx2 ny2 */
fst tempsqrx ;/* nx2 ny2 */
fadd st,st(1) ;/* nx2+ny2 ny2 */
fstp magnitude ;/* ny2 */
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfpIMAGbailout endp
asmfpORbailout proc near uses si di
fld qword ptr new+8
fmul st,st ;/* ny2 */
fst tempsqry
fld qword ptr new ;/* nx ny2 */
fmul st,st ;/* nx2 ny2 */
fst tempsqrx
fld st(1) ;/* ny2 nx2 ny2 */
fadd st,st(1) ;/* ny2+nx2 nx2 ny2 */
fstp magnitude ;/* nx2 ny2 */
fcomp rqlim ;/* ny2 */
fstsw ax ;/*** 287 and up only */
sahf
jae bailoutp
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailoutp:
finit ;/* cleans up stack */
bailout:
mov ax,1
ret
asmfpORbailout endp
asmfpANDbailout proc near uses si di
fld qword ptr new+8
fmul st,st ;/* ny2 */
fst tempsqry
fld qword ptr new ;/* nx ny2 */
fmul st,st ;/* nx2 ny2 */
fst tempsqrx
fld st(1) ;/* ny2 nx2 ny2 */
fadd st,st(1) ;/* ny2+nx2 nx2 ny2 */
fstp magnitude ;/* nx2 ny2 */
fcomp rqlim ;/* ny2 */
fstsw ax ;/*** 287 and up only */
sahf
jb nobailoutp
fcomp rqlim ;/*** stack is empty */
fstsw ax ;/*** 287 and up only */
sahf
jae bailout
jmp short nobailout
nobailoutp:
finit ;/* cleans up stack */
nobailout:
mov si,offset new
mov di,offset old
mov ax,ds
mov es,ax
mov cx,8
rep movsw
xor ax,ax
ret
bailout:
mov ax,1
ret
asmfpANDbailout endp
.8086
.8087
end